#include <stdio.h>
#include <stdlib.h>

//头插法插入链表节点，带有头结点

typedef struct Node{
    int data;
    struct Node* next;
}Node , *PNode;
//这里的*PNode解引出来是一个指向内存空间的指针，就是指向节点所在内存空间的指针。

void Insert_head (int x , PNode* p)
{
    PNode temp = (PNode)malloc(sizeof(Node));
    temp->data = x;
    temp->next =NULL;
    if ((*p) != NULL)
    {
        temp->next = (*p);
    }
    (*p) = temp;
}

void Insert_tail (int x , PNode* p)
{
    PNode temp1 = (PNode)malloc(sizeof(Node));
    temp1->data = x;

    if ((*p) == NULL)
    {
        (*p) = temp1;
        return;
    }//处理空链表的情况
    PNode temp2 = *p;
    while (temp2->next != NULL)
    {
        temp2 = temp2->next;
    }
    temp2->next = temp1;
    temp1->next = NULL;   
}

void Print (PNode* temp)//这里传入的是头结点，head作为头结点，没有数据域和指针域，可以理解为一个单纯的指向节点的地址，存放的是下一个节点的地址
{
    PNode tem = (*temp);
    while (tem != NULL)
    {
        printf ("%d\n" , tem->data);
        tem = tem->next;

    }
}

void Reverse (PNode *plist)
{
    PNode temp1 = (*plist);
    PNode temp2 , temp3 = NULL;
    while (temp1 != NULL)
    {   
        temp2 = temp1->next;
        temp1->next = temp3;
        temp3 = temp1;

        temp1 = temp2;
        
    }

    
    (*plist) = temp3;

    
    
}

int main ()
{
    PNode head = NULL;
    
    int n , x;

    scanf ("%d" , &n);

    for (int i = 0 ; i < n ; i++)
    {
        scanf ("%d" ,&x );
        Insert_tail(x , &head);//这里传入了一个指向head指针类型的指针，需要在形参的位置用二重指针进行接受
        
    }

    Print(&head);

    Reverse(&head);

    Print(&head);

    return 0;
}